# -*- coding: utf-8 -*-
'''
Created on 2019年3月24日

@author: guety
'''
import os
import copy
import datetime
import logging
import sys
import datetime
import random
DNA_SIZE = 10            # DNA length
POP_SIZE = 100           # population size
CROSS_RATE = 0.8         # mating probability (DNA crossover)
MUTATION_RATE = 0.003    # mutation probability


logging.basicConfig(level=logging.DEBUG,
                    filename='../logs/CodeCraft-2019.log',
                    format='[%(asctime)s] %(levelname)s [%(funcName)s: %(filename)s, %(lineno)d] %(message)s',
                    datefmt='%Y-%m-%d %H:%M:%S',
                    filemode='a')




class GameClass(object):
    '''
    classdocs
    '''
    def __init__(self,car_path,road_path,cross_path,answer_path):
        '''
        Constructor
        '''
        self.car_path =car_path
        self.road_path = road_path
        self.cross_path = cross_path
        self.answer_path = answer_path
        self.router_map=[]
        self.cross_num=0
        self.car_data=[]
        self.cross_data=[]
        self.map_dijkstra=[]
        self.init_data()
        self.answer()
    # find non-zero fitness for selection
    def init_data(self):
        """
        初始化路线图
        """
        cross  = open ( self.cross_path ) 
        line = cross.readline()             # 调用文件的 readline()方法
        map_demo=[]
        map_demo.append({"id":"","length":sys.maxsize,"speed":0,"channel":0,})
        while line:
            if line[0]=='#':
                line = cross.readline()
                continue
            self.cross_num+=1
            self.cross_data.append(int(line.replace('(','').replace(' ','').split(',')[0]))
            map_demo.append({"id":"","length":sys.maxsize,"speed":0,"channel":0,})         
            line = cross.readline()
        for _ in range(self.cross_num+1):
            self.router_map.append(copy.deepcopy(map_demo))
        # print( self.cross_num, self.cross_data)
        # print(self.router_map)
        # print(len(self.router_map[0]))


        """
        构建路线图
        """
        road=open(self.road_path)
        line=road.readline()
        while line:
            if line[0]=='#':
                line=road.readline()
                continue
            line_data=line.replace('(','').replace(' ','').replace(')','').replace('\n','').split(',')
            # print(line_data)
            # print(self.router_map[int(line_data[4])][int(line_data[5])],"\n",self.router_map[int(line_data[5])][int(line_data[4])])
            # print(int(line_data[4]),int(line_data[5]))
            if int (line_data[-1])==1:
                self.router_map[int(line_data[4])][int(line_data[5])]["id"]=line_data[0]
                self.router_map[int(line_data[5])][int(line_data[4])]["id"]=line_data[0]
                self.router_map[int(line_data[4])][int(line_data[5])]["length"]=int(line_data[1])
                self.router_map[int(line_data[5])][int(line_data[4])]["length"]=int(line_data[1])
                self.router_map[int(line_data[4])][int(line_data[5])]["speed"]=int(line_data[2])
                self.router_map[int(line_data[5])][int(line_data[4])]["speed"]=int(line_data[2])
                self.router_map[int(line_data[4])][int(line_data[5])]["channel"]=int(line_data[3])
                self.router_map[int(line_data[5])][int(line_data[4])]["channel"]=int(line_data[3])
            else:
                # print("\n\n")
                self.router_map[int(line_data[4])][int(line_data[5])]["id"]=line_data[0]
                self.router_map[int(line_data[4])][int(line_data[5])]["length"]=int(line_data[1])
                self.router_map[int(line_data[4])][int(line_data[5])]["speed"]=int(line_data[2])
                self.router_map[int(line_data[4])][int(line_data[5])]["channel"]=int(line_data[3])
            # print(self.router_map[int(line_data[4])][int(line_data[5])],"\n",self.router_map[int(line_data[5])][int(line_data[4])])
            line=road.readline()
        for i  in range(self.cross_num+1):
            data=self.dijkstra(i)
            self.map_dijkstra.append(data)
            # print(data)
            # for j  in range(self.cross_num):
            #     if self.router_map[i][j]["speed"]!=0:
            #         print(self.router_map[i][j])
        """
        构建车辆数据
        """
        #print(len(self.map_dijkstra))
        car=open( self.car_path)
        line=car.readline()
        while line: 
            if line[0]=='#':
                line=car.readline()
                continue
            line_data=line.replace('(','').replace(' ','').replace(')','').replace('\n','').split(',')
            #router=self.dijkstra(int(line_data[1]),int(line_data[2]))
            #print(int(line_data[1]))
            path=self.map_dijkstra[int(line_data[1])]
            result = []
            temp=int(line_data[2])
            while True:
                result.append(temp)
                if temp != int(line_data[1]):
                    if temp >=0:
                        temp=path[temp]
                    else:
                        result=[]
                        break
                else:
                    break
            router=[]
            i=0
            for x in range(len(result)-1,-1,-1):
                router.append(result[x])
            # print(router)
            self.car_data.append({"id":line_data[0],"from":int(line_data[1]),"to":int(line_data[2]),"speed":int(line_data[3]),"planTime":int(line_data[4]),"realTime":random.randint(int(line_data[4]),900),"router":router})  
            # print(line_data)
            line=car.readline()
    def dijkstra(self, startIndex):
        """
        求解各节点最短路径，获取path，和cost数组，
        path[i] 表示vi节点的前继节点索引，一直追溯到起点。
        cost[i] 表示vi节点的花费
        """
        graph=copy.deepcopy(self.router_map)
        lenth = len(graph)
        max=sys.maxsize
        path = [0] * lenth
        cost = [0] * lenth
        v = [0] * lenth
        # 初始化 path，cost，V
        for i in range(lenth):
            if i == startIndex:
                v[startIndex] = 1
            else:
                cost[i] = graph[startIndex][i]["length"]
                path[i] = (startIndex if (cost[i] < max) else -1)
        # print v, cost, path
        for i in range(1, lenth):
            minCost = max
            curNode = -1
            for w in range(lenth):
                if v[w] == 0 and cost[w] < minCost:
                    minCost = cost[w]
                    curNode = w
            # for 获取最小权值的节点
            if curNode == -1: break
            # 剩下都是不可通行的节点，跳出循环
            v[curNode] = 1
            for w in range(lenth):
                if v[w] == 0 and (graph[curNode][w]["length"] + cost[curNode] < cost[w]):
                    cost[w] = graph[curNode][w]["length"] + cost[curNode] # 更新权值
                    path[w] = curNode # 更新路径
            # for 更新其他节点的权值（距离）和路径
        return path
    def answer(self):
        fo = open(self.answer_path, "w")
        for x in self.car_data:
            router=""
            for i in range(len(x["router"])-1):
                router=router+","+str(self.router_map[x["router"][i]][x["router"][i+1]]["id"])
            car_str="("+str(x["id"])+","+str(x["realTime"])+router+')\n'
            fo.write(car_str)
        fo.close()
    def get_fitness(self,pred):
        pass
    def translateDNA(self,pop):
        pass
    def select(self,pop, fitness): # nature selection wrt pop's fitness
        pass 
    def crossover(self, parent, pop):#遗传
        pass
    def mutate(self, child):#变异
        pass


def main():
    if len(sys.argv) != 5:
        logging.info('please input args: car_path, road_path, cross_path, answerPath')
        exit(1)

    car_path = sys.argv[1]
    road_path = sys.argv[2]
    cross_path = sys.argv[3]
    answer_path = sys.argv[4]

    logging.info("car_path is %s" % (car_path))
    logging.info("road_path is %s" % (road_path))
    logging.info("cross_path is %s" % (cross_path))
    logging.info("answer_path is %s" % (answer_path))
    ga=GameClass(car_path,road_path,cross_path,answer_path)

# to read input file
# process
# to write output file


if __name__ == "__main__":
    starttime = datetime.datetime.now()
    main()
    endtime = datetime.datetime.now()
    # print ((endtime - starttime).seconds)
    # cd C:\Users\guety\Documents\VScode\SDK\SDK_python\CodeCraft-2019\src 
    # python CodeCraft-2019.py ../config/car.txt ../config/road.txt ../config/cross.txt ../config/answer.txt


    """

    cd /home/yannick/桌面/SDK_python/CodeCraft-2019/src && python CodeCraft-2019.py ../config/car.txt ../config/road.txt ../config/cross.txt ../config/answer.txt

    """